package io.github.chutian0610.sqlparser.token

import arrow.core.Option
import arrow.core.getOrElse

sealed class LiteralEnum(open val text: String) {
    /** Number Literal */
    data class Number(override val text: String, val declaredType: NumberType?) : LiteralEnum(text)

    /** String Literal, i.e: 'string' */
    data class SingleQuotedStringLiteral(override val text: String) : LiteralEnum(text)

    /** String Literal, i.e: "string" */
    data class DoubleQuotedStringLiteral(override val text: String) : LiteralEnum(text)

    /** Byte String Literal, i.e: b'string' */
    data class SingleQuotedByteStringLiteral(override val text: String) : LiteralEnum(text)

    /** Byte String Literal, i.e: b"string" */
    data class DoubleQuotedByteStringLiteral(override val text: String) : LiteralEnum(text)

    /** "escaped" string literal, which are an extension to the SQL standard: i.e: e'first \n second' or E 'first \n second' */
    data class EscapedStringLiteral(override val text: String) : LiteralEnum(text)

    /** Unicode string(raw) */
    data class UnicodeRawStringLiteral(override val text: String) : LiteralEnum(text)

    /** Hexadecimal string literal: i.e.: X'deadbeef' */
    data class HexStringLiteral(override val text: String) : LiteralEnum(text)

    data class DollarQuotedStringLiteral(override val text: String, val tag: Option<String>) : LiteralEnum(text) {
        override fun toString(): String {
            if (tag.isNone()) {
                return "DollarQuotedStringLiteral(text=$$${text}$$)"
            }
            val tagStr = tag.getOrElse { "" }
            return "DollarQuotedStringLiteral(text=$${tagStr}$${text}$${tagStr}$)"
        }
    }
}